package twilio

import (
	"encoding/json"
	"errors"
	"log/slog"
	"net/url"
	"strconv"

	"gitee.com/gxcc/go-utils/utils"
)

type SmsClient struct {
	PhoneNumber string `json:"twilioPhoneNumber"`
	AuthSid     string `json:"twilioAuthSid"`
	AuthToken   string `json:"twilioAuthToken"`
}

func (svc *SmsClient) Send(to string, body string) error {
	reqUrl := "https://" + svc.AuthSid + ":" + svc.AuthToken +
		"@api.twilio.com/2010-04-01/Accounts/" + svc.AuthSid + "/Messages.json"
	headers := map[string]string{
		"Content-Type": "application/x-www-form-urlencoded",
	}
	var params = "From=" + svc.PhoneNumber + "&To=" + to + "&Body=" + body

	res, err := utils.HttpPost(reqUrl, headers, []byte(params))
	if err != nil {
		slog.Error(err.Error())
	}
	if len(res.Body) > 0 {
		resMap := make(map[string]string)
		if err := json.Unmarshal(res.Body, &resMap); err != nil {
			slog.Error(err.Error())
		}
		if res.Status < 200 || res.Status >= 300 {
			return errors.New(resMap["message"])
		} else {
			return nil
		}
	} else {
		return errors.New("failed to send sms")
	}
}

func (svc *SmsClient) SendWithMSSid(to string, body string, MSSid string) error {
	reqUrl := "https://" + svc.AuthSid + ":" + svc.AuthToken +
		"@api.twilio.com/2010-04-01/Accounts/" + svc.AuthSid + "/Messages.json"
	headers := map[string]string{
		"Content-Type": "application/x-www-form-urlencoded",
	}

	var reqBody = url.Values{}
	reqBody.Add("To", to)
	reqBody.Add("MessagingServiceSid", MSSid)
	reqBody.Add("Body", body)

	res, err := utils.HttpPost(reqUrl, headers, []byte(reqBody.Encode()))
	if err != nil {
		slog.Error(err.Error())
	}
	if len(res.Body) > 0 {
		resMap := make(map[string]any)
		if err := json.Unmarshal(res.Body, &resMap); err != nil {
			slog.Error(err.Error())
			slog.Error("response body:\n" + string(res.Body))
			return err
		}
		if res.Status < 200 || res.Status >= 300 {
			slog.Error("response status: " + strconv.Itoa(res.Status))
			slog.Error("response body:\n" + string(res.Body))
			return errors.New(resMap["message"].(string))
		} else {
			return nil
		}
	} else {
		return errors.New("failed to send sms")
	}
}

func (svc *SmsClient) SendCode(sign string, phone string, code string) error {
	var body = "[" + sign + "]Your verification code is: [" + code + "]"
	if err := svc.Send(phone, body); err != nil {
		return err
	}
	return nil
}

func (svc *SmsClient) SendCodeWithMSSid(sign string, phone string, code string, MSSid string) error {
	var body = "[" + sign + "]Your verification code is: [" + code + "]"
	if err := svc.SendWithMSSid(phone, body, MSSid); err != nil {
		return err
	}
	return nil
}
